package zpe.controledeacesso.model.bean;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import zpe.genericcrud.model.Entidade;

@Entity
@Table( name = "tb_usuario", schema = "dbo" )

public class Usuario implements Entidade {
	private static final long serialVersionUID = 3176814900832143343L;

	@Id
	@GeneratedValue( strategy=GenerationType.IDENTITY)
	@Column( name = "ci_usuario" )
	private Integer id;
	
	@Column( name = "nm_usuario" )
	private String descricao;
	
	@Column( name = "nm_login" )
	private String login;
	
	@Column( name = "ds_email" )
	private String email;

	@Column( name = "nm_senha" )
	private String senha;
	
	@Column( name = "fl_atualizousenha" )
	private String atualizouSenha = "N";
	
	@Column( name = "dt_criacao" )
	private Date dataCriacao;
		
	@ManyToMany( fetch = FetchType.EAGER )
	@JoinTable( name = "dbo.tb_usuariogrupos", joinColumns = @JoinColumn (name = "cd_usuario" ), inverseJoinColumns = @JoinColumn( name = "cd_grupo" ) )
	private List<GrupoDeUsuario> grupos = new ArrayList<GrupoDeUsuario>();
	
	@Transient
	private List<GrupoDeUsuario> gruposAux = new ArrayList<GrupoDeUsuario>();
	
	@Transient
	private List<Permissoes> permissoes = new ArrayList<Permissoes>();
	
	@OneToOne
	@JoinColumn( name = "cd_unidade_trabalho" , nullable = false)
	private UnidadeTrabalho unidadeDeTrabalho = new UnidadeTrabalho();
	
	public Integer getId() {
		return id;
	}
	
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * @return the senha
	 */
	public String getSenha() {
		return senha;
	}

	/**
	 * @return the permissoes
	 */
	public List<Permissoes> getPermissoes() {
		return permissoes;
	}

	public UnidadeTrabalho getUnidadeDeTrabalho() {
		return unidadeDeTrabalho;
	}

	public void setUnidadeDeTrabalho(UnidadeTrabalho unidadeDeTrabalho) {
		this.unidadeDeTrabalho = unidadeDeTrabalho;
	}

	/**
	 * @param permissoes the permissoes to set
	 */
	public void setPermissoes(List<Permissoes> permissoes) {
		this.permissoes = permissoes;
	}

	/**
	 * @param senha the senha to set
	 */
	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		if(descricao != null){
			descricao = descricao.toUpperCase();
		}
		this.descricao = descricao;
	}
	
	public List<GrupoDeUsuario> getGruposAux() {
		return gruposAux;
	}

	public void setGruposAux(List<GrupoDeUsuario> gruposAux) {
		this.gruposAux = gruposAux;
	}


	public static long getSerialVersionUID() {
		return serialVersionUID;
	}
	
	/**
	 * @return the login
	 */
	public String getLogin() {
		return login;
	}

	/**
	 * @param login the login to set
	 */
	public void setLogin(String login) {
		this.login = login;
	}

	/**
	 * @return the atualizouSenha
	 */
	public String getAtualizouSenha() {
		return atualizouSenha;
	}

	/**
	 * @param atualizouSenha the atualizouSenha to set
	 */
	public void setAtualizouSenha(String atualizouSenha) {
		this.atualizouSenha = atualizouSenha;
	}

	/**
	 * @return the dataCriacao
	 */
	public Date getDataCriacao() {
		if(dataCriacao==null)
			dataCriacao = new Date();
		return dataCriacao;
	}

	/**
	 * @param dataCriacao the dataCriacao to set
	 */
	public void setDataCriacao(Date dataCriacao) {
		this.dataCriacao = dataCriacao;
	}

	/**
	 * @return the grupos
	 */
	public List<GrupoDeUsuario> getGrupos() {
		return grupos;
	}

	/**
	 * @param grupos the grupos to set
	 */
	public void setGrupos(List<GrupoDeUsuario> grupos) {
		this.grupos = grupos;
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email the email to set
	 */
	public void setEmail(String email) {
		if(email!=null)
			email = email.toUpperCase();
		this.email = email;
	}

	public Map<String, Object> notEmptyFields() {
		Map<String, Object> map = new HashMap<String, Object>();
		if( descricao != null && !descricao.trim().isEmpty() )
			map.put("descricao", descricao);
		if( login != null && !login.trim().isEmpty() )
			map.put("login", login);
		if( email != null && !email.trim().isEmpty() )
			map.put("email", email);
		return map;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Usuario other = (Usuario) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
	public NivelAcesso getMaiorNivel(int moduloId){
		List<GrupoDeUsuario> list = new ArrayList<GrupoDeUsuario>();
		// adicionando os grupos na lista
		for (int i = 0; i < getGrupos().size(); i++) {
			if (getGrupos().get(i).getModulo().getId() == moduloId) {
				list.add(getGrupos().get(i));
			}
		}

		NivelAcesso nivelDeAcesso = NivelAcesso.INDEFINIDO;

		for (int i = 0; i < list.size(); i++) {
			if ( nivelDeAcesso.ordinal() < list.get(i).getNivelDeAcesso().ordinal() ) {
				nivelDeAcesso = list.get(i).getNivelDeAcesso();
			}
		}
		return nivelDeAcesso;
	}
}
